#include <fstream>
#include <iostream>
#include <sstream>
#include <stack>
#include <string>

using namespace std;

int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    return 0;
}

void print_stack(stack<char> operators) {
    stack<char> operators2;
    while (!operators.empty()) {
        operators2.push(operators.top());
        operators.pop();
    }
    cout << "栈目前是这样的,栈底在冒号旁边：";
    while (!operators2.empty()) {
        cout << operators2.top() << ' ';
        operators2.pop();
    }
    cout << endl;
}

void print_stack_i(stack<int> operators) {
    stack<int> operators2;
    while (!operators.empty()) {
        operators2.push(operators.top());
        operators.pop();
    }
    cout << "栈目前是这样的,栈底在冒号旁边：";
    while (!operators2.empty()) {
        cout << operators2.top() << ' ';
        operators2.pop();
    }
    cout << endl;
}

string p_to_m(string expression) {
    stack<char> operators;  // 保证先算的在栈顶
    string res;

    for (char &i : expression) {
        if (i == '#') {
            continue;
        }
        if (isdigit(i)) {
            res += i;
        } else if (i == '(') {
            operators.push(i);
            print_stack(operators);
        } else if (i == ')') {
            while (!operators.empty() && operators.top() != '(') {
                res += ' ';
                res += operators.top();
                operators.pop();
                print_stack(operators);
            }
            if (!operators.empty()) {
                operators.pop();
                print_stack(operators);
            }
        } else {  // 处理操作符
            res += ' ';
            while (!operators.empty() &&
                   precedence(operators.top()) >= precedence(i)) {
                res += operators.top();
                res += ' ';
                operators.pop();
                print_stack(operators);
            }
            operators.push(i);  // 当前操作符入栈
            print_stack(operators);
        }
        // print_stack(operators);
    }

    // 清空栈中剩余的操作符
    while (!operators.empty()) {
        if (operators.top() != '(') {
            res += ' ';
            res += operators.top();
        }
        operators.pop();
        print_stack(operators);
    }
    res = "# " + res + " #";
    return res;
}

int mycal_string(string res1) {
    stringstream ss(res1);
    string it;
    stack<int> mycal;
    while (ss >> it) {
        if (it == "#") {
            continue;  // 跳过 "#" 符号
        } else if (isdigit(it[0])) {
            mycal.push(stoi(it));  // 将字符串转换为整数后压入栈
            print_stack_i(mycal);  // 打印当前栈状态
        } else {
            int operand2 = mycal.top();
            mycal.pop();
            int operand1 = mycal.top();
            mycal.pop();
            print_stack_i(mycal);

            int result;

            // 根据操作符计算结果
            switch (it[0]) {
                case '+':
                    result = operand1 + operand2;
                    break;
                case '-':
                    result = operand1 - operand2;
                    break;
                case '*':
                    result = operand1 * operand2;
                    break;
                case '/':
                    result = operand1 / operand2;
                    break;
            }
            mycal.push(result);    // 将结果压入栈
            print_stack_i(mycal);  // 打印当前栈状态
        }
    }

    return mycal.top();  // 栈顶元素即为最终结果
}

int main() {
    ifstream file("exp.txt");
    string expression;
    if (file.is_open()) {
        getline(file, expression);
        file.close();
    } else {
        cout << "前缀表达式的txt文件打开失败。";
        return 0;
    }
    cout << "中缀表达式为:";
    cout << expression << endl << endl;

    // 保证高先算的在栈顶
    stack<char> operators;
    string res;
    res = p_to_m(expression);
    cout << "后缀表达式为:";
    cout << res << endl;
    ofstream file_out;
    file_out.open("output.txt");
    file_out << res;
    cout << "\n使用后缀表达式计算：\n";
    int res2 = mycal_string(res);
    cout << "最后结果为：" << res2 << endl;
}